package org.snackframework.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.asm.ClassReader;
import org.springframework.util.ClassUtils;

public class MethodUtils
{
	private static Log logger = LogFactory.getLog(MethodUtils.class);

	public static String[] getParameterNames(Method method)
	{
		String[] paramNames=null;
		try
		{
			paramNames = visitMethod(method).getParameterNames();
		}
		catch (IOException ex)
		{
			if (logger.isDebugEnabled())
			{
				logger
						.debug(
								"IOException whilst attempting to read '.class' file for class ["
										+ method.getDeclaringClass().getName()
										+ "] - unable to determine parameter names for method: "
										+ method, ex);
			}
		}
		return paramNames;
	}

	private static ParameterNameDiscoveringVisitor visitMethod(Method method)throws IOException
	{
		ClassReader classReader = getClassReader(method.getDeclaringClass());
		FindMethodParameterNamesClassVisitor classVisitor = new FindMethodParameterNamesClassVisitor(
				method);
		classReader.accept(classVisitor, false);
		return classVisitor;
	}

	private static ClassReader getClassReader(Class clazz) throws IOException
	{
		// 是否需要考虑同步问题
		ClassReader classReader;
		InputStream is = clazz.getResourceAsStream(ClassUtils
				.getClassFileName(clazz));
		if (is == null)
			throw new FileNotFoundException("Class file for class ["
					+ clazz.getName() + "] not found");
		try
		{
			classReader = new ClassReader(is);
		}
		finally
		{
			is.close();
		}
		return classReader;
	}
}
